﻿using Dao;
using Model;
using Dao.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace Service.Impl
{
    /// <summary>
    /// 命令的服务层
    /// </summary>
    public class CommandServiceImpl: BaseServiceImpl<string, Command>, CommandService
    {
        private CommandDao commandDao = new CommandDaoImpl();

        public CommandServiceImpl()
        {
            base.SetDao(commandDao);
            this.CommandContext = Common.CommonObject.CommandContext;
        }
        /// <summary>
        /// 解析命令
        /// </summary>
        /// <param name="cmds">命令序列</param>
        /// <returns></returns>
        public CommandParseResult ParseCommand(string command)
        {
            var cmds = Regex.Split(command.Trim(), "\\s+", RegexOptions.IgnoreCase);
            // 先查询到根命令
            if (cmds.Length >= 1)
            {
                string rootCmd = cmds[0];
                List<Command> searchCommands = commandDao.SearchByCommandNameAndView(rootCmd, this.CommandContext.View);
                if(searchCommands.Count == 1)
                {
                    // 保存最后能找到的子命令, 初始值为根命令
                    Command lastCmd = searchCommands[0];
                    // 再遍历后续的子命令
                    int i = 1;
                    // 当前命令在用户输入的命令串中的索引位置，用来作为错误提示时^的位置
                    int commandIndex = cmds[0].Length;
                    for (; i < cmds.Length; commandIndex += cmds[i].Length, i++)
                    {
                        // 查询子命令
                        if (lastCmd.SubCommand != null && lastCmd.SubCommand.Count > 0)
                        {
                            var searchSubCommand = lastCmd.SubCommand.Where(c => c.Name.StartsWith(cmds[i])).ToList();
                            if (searchSubCommand.Count == 1)
                            {
                                lastCmd = searchSubCommand[0];
                            }
                            else if (searchSubCommand.Count == 0)
                            {
                                break;
                            }
                            else
                            {
                                return CommandParseResult.CreateFailInstance("错误的命令!", commandIndex, command);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    // 命令是否解析完毕
                    if (i < cmds.Length)
                    {
                        // 判断lastCmds是否包含参数信息
                        if (lastCmd.Params != null && lastCmd.Params.Count > 0)
                        {
                            Dictionary<string, string> cmd_params = new Dictionary<string, string>();
                            // cmds后续的根据参数进行匹配
                            int j = 0;
                            for(; i < cmds.Length; i++, j++)
                            {
                                var paramValue = cmds[i];
                                commandIndex += paramValue.Length;
                                // 判断当前参数是否是用户多输入的参数
                                if (j < lastCmd.Params.Count) {
                                    var paramObject = lastCmd.Params[j];
                                    //校验参数格式是否正确
                                    bool succ = validateCommandParam(paramObject, paramValue);
                                    if (succ)
                                    {
                                        // 封装参数
                                        cmd_params.Add(paramObject.Name, paramValue);
                                    }
                                    else
                                    {
                                        return CommandParseResult.CreateFailInstance("错误的命令参数!", commandIndex, command);
                                    }
                                }
                                else
                                {
                                    return CommandParseResult.CreateFailInstance("错误的命令参数!", commandIndex, command);
                                }
                            }
                            // 判断用户是否少输入了必须的命令参数
                            if(lastCmd.Params.Count > j)
                            {
                                if (lastCmd.Params[j].Require)
                                {
                                    return CommandParseResult.CreateFailInstance("命令的参数不足!", commandIndex, command);
                                }
                                else
                                {
                                    return CommandParseResult.CreateSuccessInstance(lastCmd, cmd_params);
                                }
                            }
                            else
                            {
                                return CommandParseResult.CreateSuccessInstance(lastCmd, cmd_params);
                            }
                        }
                        else
                        {
                            return CommandParseResult.CreateFailInstance("错误的命令!", commandIndex, command);
                        }
                    }
                    else
                    {
                        if (lastCmd.CanEnd)
                        {
                            // 判断用户是否有必须的参数没有输入
                            if (lastCmd.Params != null && lastCmd.Params.Count > 0)
                            {
                                if (lastCmd.Params[0].Require)
                                {
                                    return CommandParseResult.CreateFailInstance("命令的参数不足!", commandIndex, command);
                                }
                                else
                                {
                                    return CommandParseResult.CreateSuccessInstance(lastCmd, new Dictionary<string, string>());
                                }
                            }
                            else
                            {
                                return CommandParseResult.CreateSuccessInstance(lastCmd, new Dictionary<string, string>());
                            }
                        }
                        else
                        {
                            return CommandParseResult.CreateFailInstance("未结束的命令!", commandIndex, command);
                        }
                    }
                }
                else
                {
                    return CommandParseResult.CreateFailInstance("错误的命令!", 0, command);
                }
            }
            else
            {
                return CommandParseResult.CreateFailInstance("请输入命令");
            }
        }
        
        /// <summary>
        /// 解析下一个输入项
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public CommandNextInputResult ParseNextInputCommand(string command)
        {
            var cmds = Regex.Split(command.Trim(), "\\s+", RegexOptions.IgnoreCase);
            // 先查询到根命令
            if (cmds.Length >= 1)
            {
                string rootCmd = cmds[0];
                List<Command> searchCommands = commandDao.SearchByCommandNameAndView(rootCmd, this.CommandContext.View);
                if (searchCommands.Count == 1)
                {
                    // 保存最后能找到的子命令, 初始值为根命令
                    Command lastCmd = searchCommands[0];
                    // 再遍历后续的子命令
                    int i = 1;
                    // 当前命令在用户输入的命令串中的索引位置，用来作为错误提示时^的位置
                    int commandIndex = cmds[0].Length;
                    for (; i < cmds.Length; commandIndex += cmds[i].Length, i++)
                    {
                        // 查询子命令
                        if (lastCmd.SubCommand != null && lastCmd.SubCommand.Count > 0)
                        {
                            var searchSubCommand = lastCmd.SubCommand.Where(c => c.Name.StartsWith(cmds[i])).ToList();
                            if (searchSubCommand.Count == 1)
                            {
                                lastCmd = searchSubCommand[0];
                            }
                            else if (searchSubCommand.Count == 0)
                            {
                                break;
                            }
                            else
                            {
                                if(i < cmds.Length)
                                {
                                    return CommandNextInputResult.CreateFailInstance("错误的命令!", commandIndex, command);
                                }
                                CommandNextInputResult cnir = CommandNextInputResult.CreateSuccessInstance();
                                foreach(Command c in searchSubCommand)
                                {
                                    cnir.addNextValue(c.Name, c.Description);
                                }
                                if (lastCmd.CanEnd)
                                {
                                    cnir.addNextValue("<cr>", "");
                                }
                                return cnir;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    // 命令是否解析完毕
                    if (i < cmds.Length)
                    {
                        // 判断lastCmds是否包含参数信息
                        if (lastCmd.Params != null && lastCmd.Params.Count > 0)
                        {
                            Dictionary<string, string> cmd_params = new Dictionary<string, string>();
                            // cmds后续的根据参数进行匹配
                            int j = 0;
                            for (; i < cmds.Length; i++, j++)
                            {
                                var paramValue = cmds[i];
                                commandIndex += paramValue.Length;
                                // 判断当前参数是否是用户多输入的参数
                                if (j < lastCmd.Params.Count)
                                {
                                    var paramObject = lastCmd.Params[j];
                                    //校验参数格式是否正确
                                    bool succ = validateCommandParam(paramObject, paramValue);
                                    if (succ)
                                    {
                                        // 封装参数
                                        cmd_params.Add(paramObject.Name, paramValue);
                                    }
                                    else
                                    {
                                        // 判断用户输入的参数是否是最后一个
                                        if(i == cmds.Length - 1)
                                        {
                                            if (j == lastCmd.Params.Count - 1)
                                            {
                                                return CommandNextInputResult.CreateSuccessInstance("<br>", "");
                                            }
                                            CommandNextInputResult cnir = CommandNextInputResult.CreateSuccessInstance();
                                            //暂存是否能可以结束命令
                                            var nextparam = lastCmd.Params[j + 1];
                                            cnir.addNextValue(nextparam.Format, nextparam.Description);
                                            if (!nextparam.Require)
                                            {
                                                cnir.addNextValue("<br>", "");
                                            }
                                            return cnir;
                                        }
                                        return CommandNextInputResult.CreateFailInstance("错误的命令参数!", commandIndex, command);
                                    }
                                }
                                else
                                {
                                    return CommandNextInputResult.CreateFailInstance("错误的命令参数!", commandIndex, command);
                                }
                            }
                            // 判断用户是否少输入了必须的命令参数
                            if (lastCmd.Params.Count > j)
                            {
                                var param = lastCmd.Params[j];
                                CommandNextInputResult cnir = CommandNextInputResult.CreateSuccessInstance();
                                //暂存是否能可以结束命令
                                cnir.addNextValue(param.Format, param.Description);
                                if (!param.Require)
                                {
                                    cnir.addNextValue("<br>", "");
                                }
                                return cnir;
                            }
                            else
                            {
                                return CommandNextInputResult.CreateSuccessInstance("<br>", "");
                            }
                        }
                        else
                        {
                            return CommandNextInputResult.CreateFailInstance("错误的命令!", commandIndex, command);
                        }
                    }
                    else
                    {
                        var cnir = CommandNextInputResult.CreateSuccessInstance();
                        // 判断用户是否有必须的参数没有输入
                        if (lastCmd.SubCommand != null)
                        {
                            foreach (Command c in lastCmd.SubCommand)
                            {
                                cnir.addNextValue(c.Name, c.Description);
                            }
                        }
                        if(lastCmd.Params != null && lastCmd.Params.Count > 0)
                        {
                            var p = lastCmd.Params[0];
                            cnir.addNextValue(p.Format, p.Description);
                        }
                        if (lastCmd.CanEnd)
                        {
                            cnir.addNextValue("<cr>", "");
                        }
                        return cnir;
                    }
                }
                else
                {
                    if (searchCommands.Count == 0)
                    {
                        return CommandNextInputResult.CreateFailInstance("错误的命令!", 0, command);
                    }
                    var cnir = CommandNextInputResult.CreateSuccessInstance();
                    // 判断用户是否有必须的参数没有输入
                    foreach (Command c in searchCommands)
                    {
                        cnir.addNextValue(c.Name, c.Description);
                    }
                    return cnir;
                }
            }
            else
            {
                return CommandNextInputResult.CreateFailInstance("请输入命令");
            }
        }

        /// <summary>
        /// 校验参数格式是否正确
        /// </summary>
        /// <param name="paramObject"></param>
        /// <param name="paramValue"></param>
        /// <returns></returns>
        private bool validateCommandParam(CommandParam paramObject, string paramValue)
        {
            Regex regex = new Regex(paramObject.Regex);
            return regex.IsMatch(paramValue);
        }
    }
}
